<template>
  <div :class="`editable-element groupid${elementInfo.groupId}`" ref="elementRef"
    :id="`editable-element-${elementInfo.id}`" :style="{
      zIndex: elementIndex,
    }">
    <div v-for="(item, index) in handleElementOtherIdList" :key="index">
      <!-- 锁 -->
      <div v-if="item.handleElementId == elementInfo.id && elementInfo.id">
        <div :class="['shadow', elementInfo.type === 'text' ? 'bg' : '']" :style="`top:${elementInfo.top}px; 
        left:${elementInfo.left}px; 
        width:${elementInfo.width}px;
        height:${elementInfo.height}px;`" v-if="userName != item.username">
          <div class="test-box">
            <p>
              <!-- <img :src="item.userAvatar" alt="" /> -->
              <span>{{ item.username }}</span>
            </p>
          </div>
          <i class="appIcon-iconfont appIcon-jiesuo-yuansu"></i>
          <div class="ele-mask"
            v-if="handleElementOtherIdList.findIndex((item:any) => item.handleElementId == elementInfo.id) != -1"></div>
        </div>
      </div>
    </div>
    <component :is="currentElementComponent" :elementInfo="elementInfo" :selectElement="selectElement"
      :contextmenus="contextmenus" v-if="!elementInfo.hide"></component>
  </div>
</template>

<script lang="ts">
export default {
  name: "editable-element",
};
</script>

<script lang="ts" setup>
import {
  computed,
  defineComponent,
  onMounted,
  onUnmounted,
  PropType,
  ref,
} from "vue";
import { ElementTypes, PPTElement } from "@/types/slides";
import { ContextmenuItem } from "@/components/Contextmenu/types";
import useLockElement from "@/hooks/useLockElement";
import useDeleteElement from "@/hooks/useDeleteElement";
import useCombineElement from "@/hooks/useCombineElement";
import useOrderElement from "@/hooks/useOrderElement";
import useAlignElementToCanvas from "@/hooks/useAlignElementToCanvas";
import useCopyAndPasteElement from "@/hooks/useCopyAndPasteElement";
import useSelectAllElement from "@/hooks/useSelectAllElement";
import { ElementOrderCommands, ElementAlignCommands } from "@/types/edit";
import ImageElement from "@/views/components/element/ImageElement/index.vue";
import TextElement from "@/views/components/element/TextElement/index.vue";
import ShapeElement from "@/views/components/element/ShapeElement/index.vue";
import LineElement from "@/views/components/element/LineElement/index.vue";
import ChartElement from "@/views/components/element/ChartElement/index.vue";
import TableElement from "@/views/components/element/TableElement/index.vue";
import LatexElement from "@/views/components/element/LatexElement/index.vue";
import VideoElement from "@/views/components/element/VideoElement/index.vue";
import AudioElement from "@/views/components/element/AudioElement/index.vue";
import { storeToRefs } from "pinia";
import { useMainStore, useSlidesStore } from "@/store";
import emitter, { EmitterEvents } from "@/utils/emitter";

const props: any = defineProps({
  elementInfo: {
    // type: Object as PropType<PPTElement>,
    type: Object,
    required: true,
  },
  elementIndex: {
    type: Number,
    required: true,
  },
  isMultiSelect: {
    type: Boolean,
    required: true,
  },
  selectElement: {
    type: Function as PropType<
      (e: MouseEvent, element: PPTElement, canMove?: boolean) => void
    >,
    required: true,
  },
  openLinkDialog: {
    type: Function as PropType<() => void>,
    required: true,
  },
});
// 【协同】当前登录的用户列表
const { handleElementOtherIdList } = storeToRefs(useMainStore());
const userName = ref();
onMounted(() => {
  // const userInfo: any = localStorage.getItem("userInfo");
  // userName.value = JSON.parse(userInfo).nickName;
});

const slidesStore = useSlidesStore();
const { currentSlide } = storeToRefs(slidesStore);

const currentElementComponent = computed(() => {
  const elementTypeMap = {
    [ElementTypes.IMAGE]: ImageElement,
    [ElementTypes.TEXT]: TextElement,
    [ElementTypes.SHAPE]: ShapeElement,
    [ElementTypes.LINE]: LineElement,
    [ElementTypes.CHART]: ChartElement,
    [ElementTypes.TABLE]: TableElement,
    [ElementTypes.LATEX]: LatexElement,
    [ElementTypes.VIDEO]: VideoElement,
    [ElementTypes.AUDIO]: AudioElement,
  };
  return elementTypeMap[props.elementInfo.type] || null;
});

const { orderElement } = useOrderElement();
const { alignElementToCanvas } = useAlignElementToCanvas();
const { combineElements, uncombineElements } = useCombineElement();
const { deleteElement } = useDeleteElement();
const { lockElement, unlockElement } = useLockElement();
const { copyElement, pasteElement, cutElement } = useCopyAndPasteElement();
const { selectAllElement } = useSelectAllElement();

const contextmenus = (): ContextmenuItem[] => {
  if (props.elementInfo.lock) {
    return [
      {
        text: "解锁",
        handler: () => unlockElement(props.elementInfo),
      },
    ];
  }

  let menusList = [
    {
      text: "剪切",
      subText: "Ctrl + X",
      handler: cutElement,
    },
    {
      text: "复制",
      subText: "Ctrl + C",
      handler: copyElement,
    },
    {
      text: "粘贴",
      subText: "Ctrl + V",
      handler: pasteElement,
    },
    { divider: true },
    {
      text: "水平居中",
      handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL),
      children: [
        {
          text: "水平垂直居中",
          handler: () => alignElementToCanvas(ElementAlignCommands.CENTER),
        },
        {
          text: "水平居中",
          handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL),
        },
        {
          text: "左对齐",
          handler: () => alignElementToCanvas(ElementAlignCommands.LEFT),
        },
        {
          text: "右对齐",
          handler: () => alignElementToCanvas(ElementAlignCommands.RIGHT),
        },
      ],
    },
    {
      text: "垂直居中",
      handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL),
      children: [
        {
          text: "水平垂直居中",
          handler: () => alignElementToCanvas(ElementAlignCommands.CENTER),
        },
        {
          text: "垂直居中",
          handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL),
        },
        {
          text: "顶部对齐",
          handler: () => alignElementToCanvas(ElementAlignCommands.TOP),
        },
        {
          text: "底部对齐",
          handler: () => alignElementToCanvas(ElementAlignCommands.BOTTOM),
        },
      ],
    },
    { divider: true },
    {
      text: "置于顶层",
      disable: props.isMultiSelect && !props.elementInfo.groupId,
      handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP),
      children: [
        {
          text: "置于顶层",
          handler: () =>
            orderElement(props.elementInfo, ElementOrderCommands.TOP),
        },
        {
          text: "上移一层",
          handler: () =>
            orderElement(props.elementInfo, ElementOrderCommands.UP),
        },
      ],
    },
    {
      text: "置于底层",
      disable: props.isMultiSelect && !props.elementInfo.groupId,
      handler: () =>
        orderElement(props.elementInfo, ElementOrderCommands.BOTTOM),
      children: [
        {
          text: "置于底层",
          handler: () =>
            orderElement(props.elementInfo, ElementOrderCommands.BOTTOM),
        },
        {
          text: "下移一层",
          handler: () =>
            orderElement(props.elementInfo, ElementOrderCommands.DOWN),
        },
      ],
    },
    { divider: true },
    {
      text: "设置链接",
      handler: props.openLinkDialog,
    },
    {
      text: props.elementInfo.groupId ? "取消组合" : "组合",
      subText: "Ctrl + G",
      handler: props.elementInfo.groupId ? uncombineElements : combineElements,
      hide: !props.isMultiSelect,
    },
    {
      text: "全选",
      subText: "Ctrl + A",
      handler: selectAllElement,
    },
    {
      text: "锁定",
      subText: "Ctrl + L",
      handler: lockElement,
    },
    {
      text: "删除",
      subText: "Delete",
      handler: deleteElement,
    },
  ];
  if (props.elementInfo.groupId) {
    menusList.unshift({
      text: "保存为自定义组件",
      handler: () => saveCustom(props.elementInfo),
    });
  }
  return menusList;
};
const saveCustom = (data: any) => {
  emitter.emit(EmitterEvents.CREATE_CUSTOM);
};
</script>
<style lang="scss" scoped>
.model {
  .flex {
    position: relative;

    .ant-radio-group {
      margin-top: 20px;
    }
  }

  h3 {
    font-weight: 600;
    font-size: 16px;
  }

  p {
    color: #959fba;
    font-size: 14px;
    line-height: 14px;
    margin: 15px 0;
  }

  input {
    height: 46px;
    background: #f0f1f3;
    border-radius: 10px;
    border: 1px solid rgba(240, 241, 243, 1);
  }

  button {
    position: absolute;
    right: 0;
    height: 46px;
    width: 80px;
    border-radius: 10px;
    background: #686ce8;

    &:hover,
    &:active,
    &:focus {
      background: #7a7ef0 !important;
      color: #fff;
    }
  }
}

// 协同，锁定当前其他用户操作的元素
.shadow {
  text-align: center;
  position: absolute;
  top: 0;
  z-index: 99;
  display: flex;
  justify-content: center;
  align-items: center;

  .ele-mask {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    background: rgba(122, 132, 255, 0.12);
    border-radius: 2px;
  }

  .iconfont {
    width: 32px;
    height: 32px;
    background: #ffffff;
    box-shadow: 0px 4px 5px 0px rgba(110, 117, 198, 0.12);
    font-size: 16px;
    line-height: 32px;
    border-radius: 50%;
    display: inline-block;
    color: #7a84ff;
  }

  .test-box {
    position: absolute;
    top: -56px;
    width: 100%;
    left: 0;

    p {
      display: inline-block;
      width: auto;
      height: 36px;
      line-height: 36px;
      background: #ffffff;
      box-shadow: 0px 4px 5px 0px rgba(110, 117, 198, 0.12);
      border-radius: 18px;
      font-size: 14px;
      padding: 0 15px;
      margin: 0 auto;
    }
  }
}

.shadow.bg {
  background: rgba(0, 0, 0, 0.3);
}
</style>
